home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 145 / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin / tools / sharp / sxwork3.lzh / サンプル実用編 / 小遣い帳 / CSCELL.C < prev    next >
Text File  |  1994-03-10  |  24KB  |  841 lines

  1. /******************************************************************************
  2.  *    cscell.c:    表計算用パッケージ
  3.  ******************************************************************************
  4.  *    Workroom SX-68K Sample Program Copyright 1994 SHARP
  5.  */
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <string.h>
  9. #include <event.h>        /* イベントマンを利用するときに必要    */
  10. #include <sxgraph.h>        /* グラフ系マネージャを利用するときに必要 */
  11. #include <text.h>        /* テキストマンを利用するときに必要    */
  12. #include <task.h>        /* タスクマンを利用するときに必要    */
  13. #include "cash.h"        /* このプログラム固有のヘッダファイル    */
  14.  
  15. /******************************************************************************
  16.  *    openCell():    セルのワークを作成する
  17.  ******************************************************************************
  18.  *    引数:    Mtx *mp        表の構造体へのポインタ
  19.  *        Window *winPtr    ウィンドウポインタ
  20.  *    戻り値:    BOOLEAN        = TRUE:  作成成功
  21.  *                = FALSE: 作成失敗
  22.  */
  23. BOOLEAN openCell(Mtx *mp, Window *winPtr, LPoint lpt, int wide, int height, int fsize)
  24. {
  25.     int errCode;
  26.  
  27.     static Rect rctext = { 0, 0, 12, 12 };
  28.  
  29.     /* セルの表示位置を設定 */
  30.     mp->pos.x_y = lpt;
  31.     /* セルの大きさを設定 */
  32.     mp->cWide = wide;
  33.     mp->cHeight = height;
  34.     /* フォントサイズを設定 */
  35.     mp->fontSize = fsize;
  36.  
  37.     /* セル編集関係のフラグを初期化 */
  38.     mp->mCell.x = 0;
  39.     mp->mCell.y = 0;
  40.     mp->eCell.x = 0;
  41.     mp->eCell.y = 0;
  42.     mp->focus = 0;
  43.     mp->tEdit = NULL;
  44.     mp->edit = FALSE;
  45.  
  46.     errCode = TMNew2(&rctext, &rctext, &winPtr->graph, &mp->tEdit);
  47.     if (errCode < 0)
  48.         return FALSE;
  49.  
  50.     TMHide(mp->tEdit);
  51.     (*mp->tEdit)->lenMax = 1;
  52.     (*mp->tEdit)->lineHeight = mp->fontSize * 2;
  53.     (*mp->tEdit)->editMode = 0;    /* 編集モードを通常表示にする    */
  54.     /* ファンクションキーアサインテーブルを設定する */
  55.     (*mp->tEdit)->funcCode = funcKeyTbl;
  56.  
  57.     return TRUE;
  58. }
  59.  
  60. /******************************************************************************
  61.  *    closeCell():    セルを廃棄する
  62.  ******************************************************************************
  63.  *    引数:    Mtx *mp        表の構造体へのポインタ
  64.  *        Window *winPtr    ウィンドウポインタ
  65.  */
  66. void closeCell(Mtx *mp, Window *winPtr)
  67. {
  68.     GMSetGraph(&winPtr->graph);
  69.     mp->edit = FALSE;
  70.     mp->eCell.x = 0;
  71.     mp->eCell.y = 0;
  72.     mp->focus = 0;
  73.     mp->cAttH = NULL;
  74.     mp->cTitle = NULL;
  75.     mp->cData = NULL;
  76.  
  77.     if (mp->tEdit != NULL) {
  78.         TMCaret(mp->tEdit, 0);
  79.         TMDispose(mp->tEdit);    /* テキストを廃棄する    */
  80.         mp->tEdit = NULL;
  81.     }
  82.  
  83.     addUpdate(winPtr, &mp->rcAll);
  84. }
  85.  
  86. /******************************************************************************
  87.  *    setCellData():    セルのデータ配列を設定
  88.  ******************************************************************************
  89.  *    引数:    Mtx *mp        表の構造体へのポインタ
  90.  */
  91. void setCellData(Mtx *mp, CAtt *ha, char **data, char ***tBuff)
  92. {
  93.     int i;
  94.  
  95.     mp->cAttH = ha;
  96.     mp->cTitle = tBuff;
  97.     mp->cData = data;
  98.  
  99.     /* 全体のレクタングルを求める */
  100.     mp->rcAll.l.l_t = 0;
  101.     mp->rcAll.d.right = 0;
  102.     for (i = 0; i < mp->cWide; i++)
  103.         mp->rcAll.d.right += (mp->cAttH + i)->length * mp->fontSize + CELLMG * 2;
  104.     mp->rcAll.d.right += OUTFRM * 2;
  105.     mp->rcAll.d.bottom = (mp->fontSize * 2 + CELLMG * 2) * mp->cHeight + (mp->fontSize * 2 + CELLMG * 2 + 1) * 2 + OUTFRM * 2;
  106.     GMSlideRect(&mp->rcAll, mp->pos.x_y);
  107.  
  108.     /* データセルまでのオフセット */
  109.     mp->offset.p.x = OUTFRM;
  110.     mp->offset.p.y = (mp->fontSize * 2 + CELLMG * 2) + 1 + OUTFRM;
  111. }
  112.  
  113. /******************************************************************************
  114.  *    drawCell():    セル全体の描画
  115.  ******************************************************************************
  116.  *    引数:    Mtx *mp        表の構造体へのポインタ
  117.  */
  118. void drawCell(Mtx *mp)
  119. {
  120.     int i, x, dx;
  121.     CPoint cpt;
  122.     Rect rc;
  123.  
  124.     GMAPage(G_PAGE0 | G_PAGE1);    /* アクセスページを0と1ページにする */
  125.     drawCellFrame(&mp->rcAll, 2, 0);
  126.     rc = mp->rcAll;
  127.     GMInsetRect(&rc, LONGWORD(OUTFRM - 1, OUTFRM - 1));
  128.     drawCellFrame(&rc, 2, 1);
  129.  
  130.     /* y座標は固定 */
  131.     rc.d.top = mp->pos.p.y + OUTFRM;
  132.     rc.d.bottom = rc.d.top + mp->fontSize * 2 + CELLMG * 2;
  133.     /* タイトルバーを描画する */
  134.     x = 0;
  135.     for (i = 0; i < mp->cWide; i++) {
  136.         dx = (mp->cAttH + i)->length * mp->fontSize + CELLMG * 2;
  137.         rc.d.left = mp->pos.p.x + OUTFRM;
  138.         rc.d.right = rc.d.left + dx;
  139.         GMSlideRect(&rc, x << 16);
  140.         /* タイトルフレームを描画 */
  141.         drawCellFrame(&rc, 2, 0);
  142.         /* タイトル文字列を影付きで描画 */
  143.         GMShadowStrZ(*(*mp->cTitle + i), LONGWORD(rc.d.left + CELLMG, rc.d.top + CELLMG));
  144.         x += dx;
  145.     }
  146.     /* データセルを描画 */
  147.     for (cpt.y = 0; cpt.y < mp->cHeight; cpt.y++)
  148.         for (cpt.x = 0; cpt.x < mp->cWide; cpt.x++)
  149.             drawCellOne(mp, &cpt);
  150.  
  151.     /* 合計用入力欄を描画 */
  152.     x = 0;
  153.     cpt.y = mp->cHeight;
  154.     rc.d.top = mp->pos.p.y + mp->offset.p.y + mp->cHeight * (mp->fontSize * 2 + CELLMG * 2) + 1;
  155.     rc.d.bottom = rc.d.top + (mp->fontSize * 2 + CELLMG * 2);
  156.     for (i = 0; i < mp->cWide; i++) {
  157.         dx = (mp->cAttH + i)->length * mp->fontSize + CELLMG * 2;
  158.         if ((mp->cAttH + i)->attrib == 0)
  159.             /* 数値の場合、合計金額を計算 */
  160.             totalCell(mp, i);
  161.         else {
  162.             /* 数値以外の場合描画のみ */
  163.             rc.d.left = mp->pos.p.x + OUTFRM;
  164.             rc.d.right = rc.d.left + dx;
  165.             GMSlideRect(&rc, x << 16);
  166.             /* セルのフレームを描画 */
  167.             drawCellFrame(&rc, (mp->cAttH + i)->attrib, 0);
  168.             cpt.x = i;
  169.             drawCellStr(mp, &rc, &cpt);
  170.         }
  171.         x += dx;
  172.     }
  173. }
  174.  
  175. /******************************************************************************
  176.  *    drawCellOne():    1つのセルを描画
  177.  ******************************************************************************
  178.  *    引数:    Mtx *mp        表の構造体へのポインタ
  179.  *        CPoint *pcpt    セルの位置へのポインタ
  180.  */
  181. void drawCellOne(Mtx *mp, CPoint *pcpt)
  182. {
  183.     int lastFC, lastBC;
  184.     Rect rc;
  185.     CAtt *pcatt;
  186.  
  187.     lastFC = GMForeColor(G_BLACK);
  188.     lastBC = GMBackColor(G_LGRAY);
  189.     /* セルの大きさを求める */
  190.     rc.l.l_t = 0;
  191.     rc.d.right = (mp->cAttH + pcpt->x)->length * mp->fontSize + CELLMG * 2;
  192.     rc.d.bottom = mp->fontSize * 2 + CELLMG * 2;
  193.  
  194.     /* セル位置にレクタングルを移動 */
  195.     GMSlideRect(&rc, cptToLpt(mp, pcpt));
  196.  
  197.     /* セルのフレームを描画 */
  198.     pcatt = mp->cAttH + pcpt->x;
  199.     drawCellFrame(&rc, pcatt->attrib, 0);
  200.     drawCellStr(mp, &rc, pcpt);
  201.     GMForeColor(lastFC);
  202.     GMBackColor(lastBC);
  203. }
  204.  
  205. /******************************************************************************
  206.  *    drawCellStr():    セル内に文字列を描画
  207.  ******************************************************************************
  208.  *    引数:    Mtx *mp        表の構造体へのポインタ
  209.  *        CPoint *pcpt    セルの位置へのポインタ
  210.  */
  211. void drawCellStr(Mtx *mp, Rect *prc, CPoint *pcpt)
  212. {
  213.     int lastFC, lastBC;
  214.     Point pt;
  215.     CAtt *pcatt;
  216.     char str[256], *ar;
  217.  
  218.     lastFC = GMForeColor(G_BLACK);
  219.     lastBC = GMBackColor(G_LGRAY);
  220.  
  221.     pt.p.x = prc->d.left + CELLMG;
  222.     pt.p.y = prc->d.top + CELLMG;
  223.     /* 格納データのポインタを取得 */
  224.     pcatt = mp->cAttH + pcpt->x;
  225.     ar = *(mp->cData + pcatt->array);
  226.     switch (pcatt->attrib) {
  227.     case 0:                /* 数値            */
  228.         /* 数値文字列を右揃えで出力 */
  229.         GMBackColor(G_WHITE);
  230.         sprintf(str, "%*d\0", pcatt->length - 1, *((int *) ar + pcpt->y));
  231.         GMMove(pt.x_y);
  232.         GMDrawStrZ(str);
  233.         break;
  234.     case 1:                /* 文字列        */
  235.         /* 文字列を左揃えで出力 */
  236.         GMBackColor(G_WHITE);
  237.         strcpy(str, ar + pcpt->y * pcatt->size);
  238.         GMMove(pt.x_y);
  239.         GMDrawStrZ(str);
  240.         break;
  241.     case 2:                /* タイトル        */
  242.         /* タイトル文字列を影付きで出力 */
  243.         GMBackColor(G_LGRAY);
  244.         GMShadowStrZ(*(*(mp->cTitle + 1) + pcpt->y), pt.x_y);
  245.         break;
  246.     }
  247.     GMForeColor(lastFC);
  248.     GMBackColor(lastBC);
  249. }
  250.  
  251. /******************************************************************************
  252.  *    drawCellFrame():    セルのフレームを描画
  253.  ******************************************************************************
  254.  *    引数:    Mtx *mp        表の構造体へのポインタ
  255.  *        short kind    フレームを作成するセルのデータの種類
  256.  *        short mode    フレームの状態
  257.  *                = 0: 通常表示
  258.  *                = 1: 選択状態
  259.  */
  260. void drawCellFrame(Rect *prc, short kind, short mode)
  261. {
  262.     int lastFC, lastBC, lc, rc;
  263.     Point pt;
  264.  
  265.     lastFC = GMForeColor(G_BLACK);
  266.     lastBC = GMBackColor(G_LGRAY);
  267.  
  268.     switch (kind) {
  269.     case 0:
  270.     case 1:
  271.         GMForeColor(G_WHITE);
  272.         GMFillRect(prc);
  273.         GMForeColor(G_BLACK);
  274.         GMMove(LONGWORD(prc->d.right - 1, prc->d.top));
  275.         GMLine(LONGWORD(prc->d.right - 1, prc->d.bottom - 1));
  276.         GMMove(LONGWORD(prc->d.left, prc->d.bottom-1));
  277.         GMLine(LONGWORD(prc->d.right - 1, prc->d.bottom - 1));
  278.         break;
  279.     case 2:
  280.         if (mode == 1) {    /* mode = 1なら、窪んだレクタングル */
  281.             lc = G_BLACK;
  282.             rc = G_WHITE;
  283.         } else {        /* mode = 0なら、浮き出たレクタングル */
  284.             lc = G_WHITE;
  285.             rc = G_BLACK;
  286.         }
  287.         /* 光沢部分 */
  288.         lastFC = GMForeColor(lc);
  289.         pt.p.x = prc->d.left;
  290.         pt.p.y = prc->d.bottom - 1;
  291.         GMMove(pt.x_y);
  292.         pt.p.y = prc->d.top;
  293.         GMLine(pt.x_y);
  294.         pt.p.x = prc->d.right - 2;
  295.         GMLine(pt.x_y);
  296.         /* 光沢と影の境 */
  297.         GMForeColor(G_DGRAY);
  298.         pt.p.x++;
  299.         GMMove(pt.x_y);
  300.         GMLine(pt.x_y);
  301.         /* 影の部分 */
  302.         GMForeColor(rc);
  303.         pt.p.y++;
  304.         GMMove(pt.x_y);
  305.         pt.p.y = prc->d.bottom - 1;
  306.         GMLine(pt.x_y);
  307.         pt.p.x = prc->d.left + 1;
  308.         GMLine(pt.x_y);
  309.         /* 光沢と影の境 */
  310.         GMForeColor(G_DGRAY);
  311.         pt.p.x--;
  312.         GMMove(pt.x_y);
  313.         GMLine(pt.x_y);
  314.     }
  315.     GMForeColor(lastFC);
  316.     GMBackColor(lastBC);
  317. }
  318.  
  319. /******************************************************************************
  320.  *    cptToLpt():    セルの座標から物理座標を求める
  321.  ******************************************************************************
  322.  *    引数:    Mtx *mp        表の構造体へのポインタ
  323.  *        CPoint *pcpt    セルの位置へのポインタ
  324.  *    戻り値:    LPoint
  325.  */
  326. LPoint cptToLpt(Mtx *mp, CPoint *pcpt)
  327. {
  328.     int i;
  329.     Point pt;
  330.  
  331.     /* 縦方向の位置を算出 */
  332.     pt.p.y = (mp->fontSize * 2 + CELLMG * 2) * pcpt->y;
  333.     /* 横方向の位置を算出 */
  334.     pt.p.x = 0;
  335.     for (i = 0; i < pcpt->x; i++)
  336.         pt.p.x += (mp->cAttH + i)->length * mp->fontSize + CELLMG * 2;
  337.  
  338.     /* 表示開始座標を加算 */
  339.     pt.p.x += mp->pos.p.x + mp->offset.p.x;
  340.     pt.p.y += mp->pos.p.y + mp->offset.p.y;
  341.     return pt.x_y;
  342. }
  343.  
  344. /******************************************************************************
  345.  *    focusOn():    編集領域を設定
  346.  ******************************************************************************
  347.  *    引数:    Mtx *mp        表の構造体へのポインタ
  348.  *        CPoint *pcpt    セルの位置へのポインタ
  349.  */
  350. void focusOn(Mtx *mp, CPoint *pcpt)
  351. {
  352.     Rect rc;
  353.     CAtt *pcatt;
  354.     char str[256], *ar;
  355.  
  356.     pcatt = mp->cAttH + pcpt->x;
  357.     if (mp->focus == 2 || pcatt->attrib > 1)
  358.         /* すでに編集状態/数値、文字以外の属性 */
  359.         return;
  360.  
  361.     mp->eCell = *pcpt;
  362.     if (mp->focus == 0) {
  363.         mp->focus++;
  364.         /* 選択状態の1段階 */
  365.         return;
  366.     }
  367.     mp->focus = 2;
  368.     /* 選択状態の第2段階 */
  369.     /* 編集セルのレクタングルを求める */
  370.     rc.l.l_t = 0;
  371.     rc.d.right = pcatt->length * mp->fontSize + CELLMG * 2;
  372.     rc.d.bottom = mp->fontSize * 2 + CELLMG * 2;
  373.     GMSlideRect(&rc, cptToLpt(mp, pcpt));
  374.  
  375.     (*mp->tEdit)->lenMax = pcatt->length - 1; /* 編集文字数を設定 */
  376.     GMInsetRect(&rc, LONGWORD(CELLMG, CELLMG));
  377.  
  378.     /* セル内のデータを編集できるように変換 */
  379.     ar = *(mp->cData + pcatt->array);
  380.     switch (pcatt->attrib) {
  381.     case 0:                /* 数値文字列を右揃えで出力    */
  382.         sprintf(str, "%*d\0", pcatt->length - 1, *((int *) ar + pcpt->y));
  383.         break;
  384.     case 1:                /* 文字列を左揃えで出力        */
  385.         strcpy(str, (ar + pcpt->y * pcatt->size));
  386.         break;
  387.     }
  388.     TMSetText(mp->tEdit, str, (int) strlen(str));
  389.     TMSetRect(mp->tEdit, &rc, &rc);
  390.     TMShow(mp->tEdit);
  391.     TMSetSelect(mp->tEdit, 0, (*mp->tEdit)->length, 0);
  392.     TMCaret(mp->tEdit, 1);
  393.  
  394.     mp->edit = FALSE;
  395. }
  396.  
  397. /******************************************************************************
  398.  *    focusOff():    編集レベルを1つ下げる
  399.  ******************************************************************************
  400.  *    引数:    Mtx *mp        表の構造体へのポインタ
  401.  */
  402. void focusOff(Mtx *mp)
  403. {
  404.     int lastFC;
  405.     Rect rc;
  406.     CAtt *pcatt = mp->cAttH + mp->eCell.x;
  407.  
  408.     if (mp->focus == 0)
  409.         /* 編集中のセルがない */
  410.         return;
  411.  
  412.     if (mp->focus == 2) {
  413.         TMCaret(mp->tEdit, 0);
  414.         TMHide(mp->tEdit);
  415.     }
  416.     /* 編集セルのレクタングルを求める */
  417.     rc.l.l_t = 0;
  418.     rc.d.right = pcatt->length * mp->fontSize + CELLMG * 2;
  419.     rc.d.bottom = mp->fontSize * 2 + CELLMG * 2;
  420.     GMSlideRect(&rc, cptToLpt(mp, &mp->eCell));
  421.     lastFC = GMForeColor(G_WHITE);
  422.     GMFillRect(&rc);
  423.     drawCellOne(mp, &mp->eCell);    /* セルの再描画        */
  424.     mp->focus--;
  425.     mp->edit = FALSE;
  426.     drawFocus(mp);
  427.     GMForeColor(lastFC);
  428. }
  429.  
  430. /******************************************************************************
  431.  *    drawFocus():    編集領域の描画
  432.  ******************************************************************************
  433.  *    引数:    Mtx *mp        表の構造体へのポインタ
  434.  */
  435. void drawFocus(Mtx *mp)
  436. {
  437.     int lastBC, lastFC;
  438.     Rect rc, rc2;
  439.     CAtt *pcatt = mp->cAttH + mp->eCell.x;
  440.  
  441.     if (mp->focus == 0)
  442.         /* 編集中のセルがない */
  443.         return;
  444.  
  445.     /* 編集セルのレクタングルを求める */
  446.     rc.l.l_t = 0;
  447.     rc.d.right = pcatt->length * mp->fontSize + CELLMG * 2;
  448.     rc.d.bottom = mp->fontSize * 2 + CELLMG * 2;
  449.     GMSlideRect(&rc, cptToLpt(mp, &mp->eCell));
  450.     lastFC = GMForeColor(G_BLACK);
  451.     lastBC = GMBackColor(G_WHITE);
  452.  
  453.     GMFrameRect(&rc);
  454.     rc2.l.l_t = LONGWORD(rc.d.left + 1, rc.d.top + 1);
  455.     rc2.l.r_b = LONGWORD(rc.d.right - 1, rc.d.bottom - 1);
  456.     GMFrameRect(&rc2);
  457.  
  458.     if (mp->focus == 2) {
  459.         TMCaret(mp->tEdit, 0);
  460.         GMInsetRect(&rc, LONGWORD(CELLMG, CELLMG));
  461.         TMUpDate(mp->tEdit, &rc); /* テキストの文字列を描画する */
  462.         TMCaret(mp->tEdit, 1);
  463.     }
  464.     GMBackColor(lastBC);
  465.     GMForeColor(lastFC);
  466. }
  467.  
  468. /******************************************************************************
  469.  *    mountFocus():    編集領域のデータを配列に登録
  470.  ******************************************************************************
  471.  *    引数:    Mtx *mp        表の構造体へのポインタ
  472.  */
  473. void mountFocus(Mtx *mp)
  474. {
  475.     int len;
  476.     char str[256];
  477.     /* 数値と文字列の配列を示すポインタを共用体にする */
  478.     union {
  479.         int *i;
  480.         char *c;
  481.     } ar;
  482.  
  483.     CAtt *pcatt = mp->cAttH + mp->eCell.x;
  484.  
  485.     if (mp->focus < 2)
  486.         /* 編集中でなければ */
  487.         return;
  488.  
  489.     if (!mp->edit)
  490.         /* 編集されていなければ */
  491.         return;
  492.  
  493.     /* ar = 配列のポインタ */
  494.     ar.c = *(mp->cData + pcatt->array);
  495.     switch (pcatt->attrib) {
  496.     case 0:                /* 文字列を数値に変換して代入    */
  497.         len = TMGetText(mp->tEdit, str, pcatt->length);
  498.         str[len] = 0;
  499.         if (sscanf(str, "%d", ar.i + mp->eCell.y) < 1)
  500.             /* 数値に変換できなければ */
  501.             *(ar.i + mp->eCell.y) = 0;
  502.         totalCell(mp, mp->eCell.x); /* 合計を再計算        */
  503.         break;
  504.     case 1:                /* 文字列を配列にコピー        */
  505.         len = TMGetText(mp->tEdit, str, pcatt->length);
  506.         str[len] = 0;
  507.         strcpy(ar.c + mp->eCell.y * pcatt->size, str);
  508.         break;
  509.     }
  510.     /* 確定したセル番号を保存 */
  511.     mp->mCell = mp->eCell;
  512. }
  513.  
  514. /******************************************************************************
  515.  *    cellEvent():    イベント毎のセルの編集処理
  516.  ******************************************************************************
  517.  *    引数:    Mtx *mp        表の構造体へのポインタ
  518.  *        TsEvent *ptsev    タスクマンイベントレコードへのポインタ
  519.  *    戻り値:    int stat    = 0: 編集しなかった
  520.  *                = 1: 編集した
  521.  *                     (マウスダウンイベントの場合ポインタが表の
  522.  *                     中ならばbit1が"1"になる。)
  523.  *                < 0: エラーコード
  524.  */
  525. int cellEvent(Mtx *mp, TsEvent *ptsev)
  526. {
  527.     int lastAP, lastFC, lastBC, lastFK;
  528.     int stat = 0;
  529.     int keyCode;            /* キーコード            */
  530.     LPoint lpt;
  531.     CPoint cpt, dcpt;
  532.  
  533.     /* アクセスページを0と1ページにする */
  534.     lastAP = GMAPage(G_PAGE0 | G_PAGE1);
  535.     lastFC = GMForeColor(G_BLACK);
  536.     lastBC = GMBackColor(G_WHITE);
  537.     lastFK = GMFontKind(G_ROM12);
  538.     lpt = GMGlobalToLocal(ptsev->ev.where.x_y);
  539.     cpt = mp->eCell;
  540.     /* イベント毎に処理を行う */
  541.     switch (ptsev->ts.what) {
  542.     case E_IDLE:            /* アイドルイベント    */
  543.         if (mp->focus == 2)
  544.             stat = TMEventW(mp->tEdit, ptsev);
  545.         break;
  546.     case E_KEYDOWN:            /* キーダウンイベント    */
  547.         if (mp->focus == 0)
  548.             /* 入力状態でない場合 */
  549.             break;
  550.         /* ファンクションアサインテーブルによりキーコードを変換する */
  551.         keyCode = TMKeyToAsk(mp->tEdit, ptsev);
  552.         if (keyCode == -2) {    /* テーブルに登録されてないか? */
  553.             /* OPT.1キーが押されたか? */
  554.             if (ptsev->ev.how & KS_OPT1)
  555.                 /* ショートカットキーの処理 */
  556.                 mp->edit |= TMEventW(mp->tEdit, ptsev);
  557.             else {
  558.                 switch (ptsev->ev.whom.key.ascii) {
  559.                 case '\r':    /* リターンキーかENTERキー */
  560.                     if (mp->focus == 2) {
  561.                         mountFocus(mp); /* 編集結果を配列に保存 */
  562.                         if (mp->edit)
  563.                             stat = 1;
  564.                         focusOff(mp);
  565.                         focusOff(mp);
  566.                         /* 次のセルへ編集領域を移動 */
  567.                         dcpt.x = 0;
  568.                         dcpt.y = 1;
  569.                         nextCell(mp, &cpt, &dcpt);
  570.                     }
  571.                     focusOn(mp, &cpt);
  572.                     drawFocus(mp);
  573.                     break;
  574.                 case '\x1b':    /* ESCキー        */
  575.                     /* 入力状態を解除 */
  576.                     focusOff(mp);
  577.                     break;
  578.                 default:    /* その他のキー        */
  579.                     /* セルの入力を開始 */
  580.                     if (mp->focus == 1) {
  581.                         focusOn(mp, &mp->eCell);
  582.                         drawFocus(mp);
  583.                     }
  584.                     mp->edit |= TMEventW(mp->tEdit, ptsev);
  585.                     mp->edit |= stat;
  586.                     break;
  587.                 }
  588.             }
  589.         } else if (mp->focus == 1) {
  590.             /* 変換されたキーコードの場合 */
  591.             dcpt.x = 0;
  592.             dcpt.y = 0;
  593.             switch (keyCode) {
  594.             case 0x04:    /* K_RIGHT        */
  595.                 dcpt.x = 1;
  596.                 goto cursor;
  597.             case 0x13:    /* K_LEFT        */
  598.                 dcpt.x = -1;
  599.                 goto cursor;
  600.             case 0x05:    /* K_UP            */
  601.                 dcpt.y = -1;
  602.                 goto cursor;
  603.             case 0x18:    /* K_DOWN        */
  604.                 dcpt.y = 1;
  605. cursor:
  606.                 mountFocus(mp); /* 編集結果を配列に保存 */
  607.                 if (mp->edit)
  608.                     stat = 1;
  609.                 focusOff(mp);
  610.                 focusOff(mp);
  611.                 /* 次のセルへ編集領域を移動 */
  612.                 nextCell(mp, &cpt, &dcpt);
  613.                 focusOn(mp, &cpt);
  614.                 drawFocus(mp);
  615.                 break;
  616.             default:
  617.                 /* その他のキーの場合 */
  618.                 focusOn(mp, &mp->eCell);
  619.                 drawFocus(mp);
  620.                 mp->edit |= TMEventW(mp->tEdit, ptsev);
  621.                 mp->edit |= stat;
  622.             }
  623.         } else {
  624.             /* その他のキーの場合 */
  625.             mp->edit |= TMEventW(mp->tEdit, ptsev);
  626.             mp->edit |= stat;
  627.         }
  628.         break;
  629.     case E_MSLDOWN:            /* マウスレフトダウンイベント    */
  630.         if (!checkCpt(mp, lpt, &cpt)) {
  631.             /* ポインタがセルの範囲外 */
  632.             mountFocus(mp); /* 編集結果を配列に保存    */
  633.             if (mp->edit)
  634.                 stat = 1;
  635.             focusOff(mp);
  636.             focusOff(mp);
  637.             break;
  638.         }
  639.         if (mp->eCell.x != cpt.x || mp->eCell.y != cpt.y || mp->focus == 0) {
  640.             /* 以前と違うセルが選択された場合 */
  641.             mountFocus(mp); /* 編集結果を配列に保存    */
  642.             if (mp->edit)
  643.                 stat = 1;
  644.             focusOff(mp);
  645.             focusOff(mp);
  646.             /* 編集領域を移動 */
  647.             focusOn(mp, &cpt);
  648.             drawFocus(mp);
  649.         } else if (mp->focus == 2)
  650.             /* テキストのイベント処理 */
  651.             mp->edit |= TMEventW(mp->tEdit, ptsev);
  652.         else if (mp->focus == 1) {
  653.             /* 編集可能状態にする */
  654.             focusOn(mp, &cpt);
  655.             drawFocus(mp);
  656.             mp->edit |= TMEventW(mp->tEdit, ptsev);
  657.         }
  658.         stat |= 2;
  659.         break;
  660.     case E_MSRDOWN:            /* マウスライトダウンイベント    */
  661.         if (GMPtInRect(&mp->rcAll, lpt)) {
  662.             if (mp->focus == 2) {
  663.                 mp->edit |= TMEventW(mp->tEdit, ptsev);
  664.                 mp->edit |= stat;
  665.             }
  666.             stat |= 2;
  667.         }
  668.         break;
  669.     }
  670.     GMAPage(lastAP);
  671.     GMForeColor(lastFC);
  672.     GMBackColor(lastBC);
  673.     GMFontKind(lastFK);
  674.  
  675.     return stat;
  676. }
  677.  
  678. /******************************************************************************
  679.  *    nextCell():    編集領域の移動の処理
  680.  ******************************************************************************
  681.  *    引数:    Mtx *mp        表の構造体へのポインタ
  682.  *        CPoint *pcpt    現在/移動後のセル位置へのポインタ
  683.  *        CPoint *pdcpt    セルの移動方向へのポインタ
  684.  *    戻り値:    LPoint
  685.  */
  686. void nextCell(Mtx *mp, CPoint *pcpt, CPoint *pdcpt)
  687. {
  688.     /* 移動後のセル位置を求める */
  689.     pcpt->x += pdcpt->x;
  690.     pcpt->y += pdcpt->y;
  691.  
  692.     if (pcpt->x < 1)
  693.         /* 最左行の場合 */
  694.         pcpt->x = 1;
  695.     else if (pcpt->x >= mp->cWide)
  696.         /* 最右行の場合 */
  697.         pcpt->x = mp->cWide - 1;
  698.     if (pcpt->y < 0)
  699.         /* 最上行の場合 */
  700.         pcpt->y = 0;
  701.     else if (pcpt->y >= mp->cHeight)
  702.         /* 最下行ののセルの場合 */
  703.         pcpt->y = mp->cHeight - 1;
  704. }
  705.  
  706. /******************************************************************************
  707.  *    checkCpt():    指定座標で示されるセル番号を求める
  708.  ******************************************************************************
  709.  *    引数:    Mtx *mp        表の構造体へのポインタ
  710.  *        LPoint lpt    ポインタ座標
  711.  *        CPoint *pcpt    セルの位置へのポインタ
  712.  *    戻り値:    BOOLEAN        = TRUE:  正常
  713.  *                = FALSE: セルが範囲外
  714.  */
  715. BOOLEAN checkCpt(Mtx *mp, LPoint lpt, CPoint *pcpt)
  716. {
  717.     int x, cx, cy;
  718.     Point pt;
  719.  
  720.     if (!GMPtInRect(&mp->rcAll, lpt))
  721.         /* 外枠より外の場合 */
  722.         return FALSE;
  723.  
  724.     pt.x_y = lpt;
  725.     pt.p.y -= mp->pos.p.y + mp->offset.p.y;
  726.     /* セル番号に変換 */
  727.     cy = pt.p.y / (mp->fontSize * 2 + CELLMG * 2);
  728.     if (pt.p.y < 0 || cy >= mp->cHeight)
  729.         /* セルが範囲外 */
  730.         return FALSE;
  731.  
  732.     pt.p.x -= mp->pos.p.x + mp->offset.p.x;
  733.     if (pt.p.x < 0)
  734.         /* セルが範囲外 */
  735.         return FALSE;
  736.  
  737.     x = 0;
  738.     for (cx = 0; cx < mp->cWide; cx++) {
  739.         /* ポインタの座標よりセルの座標が大きくなるまでループ */
  740.         x += (mp->cAttH + cx)->length * mp->fontSize + CELLMG * 2;
  741.         if (pt.p.x < x)
  742.             /* 該当セル発見 */
  743.             break;
  744.     }
  745.     if (cx >= mp->cWide)
  746.         return FALSE;
  747.  
  748.     /* セル番号を返す */
  749.     pcpt->x = cx;
  750.     pcpt->y = cy;
  751.     return TRUE;
  752. }
  753.  
  754. /******************************************************************************
  755.  *    totalCell():    指定セルの合計を求める
  756.  ******************************************************************************
  757.  *    引数:    Mtx *mp        表の構造体へのポインタ
  758.         int cx        セルのx方向の位置
  759.  *    戻り値:    BOOLEAN        = TRUE:  正常
  760.  *                = FALSE: セルが範囲外/セルの属性が数値以外
  761.  */
  762. BOOLEAN totalCell(Mtx *mp, int cx)
  763. {
  764.     int i, x, lastFC, sum;
  765.     char *ar;
  766.     Rect rc;
  767.     CPoint cpt;
  768.     CAtt *pcatt = mp->cAttH + cx;
  769.  
  770.     if (cx >= mp->cWide || pcatt->attrib != 0)
  771.         /* セルが範囲外/セルの属性が数値以外 */
  772.         return FALSE;
  773.  
  774.     /* ar = 配列のポインタ */
  775.     ar = *(mp->cData + pcatt->array);
  776.     sum = 0;
  777.     /* 合計を算出 */
  778.     for (i = 0; i < mp->cHeight; i++)
  779.         sum += *((int *) ar + i);
  780.     /* 合計を配列に保存 */
  781.     *((int *) ar + mp->cHeight) = sum;
  782.  
  783.     /* 合計用入力欄を描画 */
  784.     lastFC = GMForeColor(G_BLACK);
  785.     rc.d.top = mp->pos.p.y + mp->offset.p.y + mp->cHeight * (mp->fontSize * 2 + CELLMG * 2) + 1;
  786.     rc.d.bottom = rc.d.top + (mp->fontSize * 2 + CELLMG * 2);
  787.     x = 0;
  788.     for (i = 0; i < cx; i++)
  789.         x += (mp->cAttH + i)->length * mp->fontSize + CELLMG * 2;
  790.  
  791.     rc.d.left = mp->pos.p.x + OUTFRM;
  792.     rc.d.right = rc.d.left + pcatt->length * mp->fontSize + CELLMG * 2;
  793.     GMSlideRect(&rc, x << 16);
  794.     /* セルのフレームを描画 */
  795.     drawCellFrame(&rc, pcatt->attrib, 0);
  796.     cpt.x = cx;
  797.     cpt.y = mp->cHeight;
  798.     drawCellStr(mp, &rc, &cpt);
  799.     GMForeColor(lastFC);
  800.     return TRUE;
  801. }
  802.  
  803. /******************************************************************************
  804.  *    caretCell():    セルのカーソルの表示
  805.  ******************************************************************************
  806.  *    引数:    Mtx *mp        表の構造体へのポインタ
  807.  */
  808. void caretCell(Mtx *mp, int flag)
  809. {
  810.     if (mp->focus == 2)
  811.         TMCaret(mp->tEdit, flag);
  812. }
  813.  
  814. /******************************************************************************
  815.  *    clearCell():    セルデータの消去
  816.  ******************************************************************************
  817.  *    引数:    Mtx *mp        表の構造体へのポインタ
  818.  *        Window *winPtr    ウィンドウポインタ
  819.  */
  820. void clearCell(Mtx *mp, Window *winPtr)
  821. {
  822.     int cx, cy;
  823.     char *ar;
  824.     CAtt *pcatt;
  825.  
  826.     /* データ領域をクリア */
  827.     for (cx = 0; cx < mp->cWide; cx++) {
  828.         for (cy = 0; cy < mp->cHeight; cy++) {
  829.             pcatt = mp->cAttH + cx;
  830.             /* ar = 配列のポインタ */
  831.             ar = *(mp->cData + pcatt->array);
  832.             if (pcatt->attrib == 0)
  833.                 *((int *) ar + cy) = 0;
  834.             else if (pcatt->attrib == 1)
  835.                 *(ar + cy * pcatt->size) = 0;
  836.         }
  837.     }
  838.     /* 表全体をアップデートリージョンに登録 */
  839.     addUpdate(winPtr, &mp->rcAll);
  840. }
  841.